﻿using ProxyServer.Acme;

namespace ProxyServer.AliDns;

public class AliDnsChallengeProvider
{
    private readonly ILogger<AliDnsChallengeProvider> _logger;
    private readonly AlibabaCloud.SDK.Alidns20150109.Client _client;

    public AliDnsChallengeProvider(ILogger<AliDnsChallengeProvider> logger, AlibabaCloud.SDK.Alidns20150109.Client client)
    {
        _logger = logger;
        _client = client;
    }

    public async Task<DnsTxtRecordContext> AddTxtRecordAsync(string domainName, string txt, CancellationToken ct = default)
    {
        var (rr, rootDomainName) = SplitDomainName(domainName);

        _logger.LogDebug("[AliDns] Dns01 Challenge: {DomainName}. RootDomain:{domain}, Record value:{rr}", domainName, rootDomainName, rr);

        //var recordId = await _dnsClient.AddDomainRecordAsync(rootDomainName, rr, "TXT", txt, ct);
        var resp = await _client.AddDomainRecordAsync(new AlibabaCloud.SDK.Alidns20150109.Models.AddDomainRecordRequest
        {
            DomainName = rootDomainName,
            RR = rr,
            Type = "TXT",
            Value = txt
        });

        if (resp.StatusCode != 200)
        {
            _logger.LogInformation("Create DomainRecord failed: {@Response}", resp);
            throw new Exception("Create Domain TXT Record failed");
        }

        return new DnsTxtRecordContext(domainName, resp.Body.RecordId);
    }

    public async Task RemoveTxtRecordAsync(DnsTxtRecordContext context, CancellationToken ct = default)
    {
        var recordId = context.Txt;

        if(string.IsNullOrWhiteSpace(recordId))
        {
            return;
        }

        ct.ThrowIfCancellationRequested();
        var resp = await _client.DeleteDomainRecordAsync(new AlibabaCloud.SDK.Alidns20150109.Models.DeleteDomainRecordRequest
        {
            RecordId = recordId,
        });
    }

    private (string rr, string rootDomainName) SplitDomainName(string domainName)
    {
        var spans = domainName.Split('.').AsSpan<string>();

        var index = spans.Length - 2;

        var rr = string.Join(".", spans[..index]!);
        var domain = string.Join(".", spans[index..]!);

        return (rr, domain);
    }
}
